/*
This is part of Screenbar, which is based in part on the Litestep
shell source code.

Copyright (C) 2008-2009 Jim Babcock
Copyright (C) 1997-2009 The LiteStep Development Team

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
#include "stdafx.h"

/////////////////////////////////////////////////////////////////////////////

static ToolTipWindow *toolTip = NULL;

void openToolTip(string prefix, const ElementContext *context, Rect hoveredElementPos)
{
	if(toolTip) {
		if(toolTip->prefix == prefix
		   && toolTip->context.match(*context)
		   && toolTip->hoveredElementPos==hoveredElementPos)
		{
			return;
		}
		else
		{
			closeToolTip();
		}
	}
	
	toolTip = new ToolTipWindow(prefix, context, hoveredElementPos);
}

void closeToolTip()
{
	if(toolTip) {
		delete toolTip;
		toolTip = NULL;
	}
}

void updateToolTip()
{
	if(toolTip)
		toolTip->checkForUpdates();
}

/////////////////////////////////////////////////////////////////////////////

ToolTipWindow::ToolTipWindow(string prefix, const ElementContext *context, Rect hoveredElementPos)
	:ScreenbarWindow(prefix, context->window->getMonitor())
{
	this->prefix = prefix;
	this->context = *context;
	this->hoveredElementPos = hoveredElementPos;
	
	this->context.vertical = getConfigBool("Vertical", false, prefix.c_str());
	this->thickness = getConfigInt("Thickness", 16, prefix.c_str());
	
	this->minLength = getConfigInt("MinLength", 0, prefix.c_str());
	this->maxLength = getConfigInt("MaxLength", 1000, prefix.c_str());

	this->alwaysOnTop = true;
	
	visibleRect = Rect(0,0,0,0);
	
	if(this->context.vertical) {
		visibleRect.width = thickness;
		visibleRect.height = maxLength;
	} else {
		visibleRect.width = maxLength;
		visibleRect.height = thickness;
	}
	
	ElementContext rootContext = *context;
	rootContext.window = this;
	initLayout(&rootContext);
	
	// Create the window
	HWND parentWindow = GetDesktopWindow();
	initWindow(WS_POPUP, parentWindow);
	layout->update();
	
	// Adjust the size of the dialog according to the length of its contents
	ElementSize layoutLength = layout->getLength();
	int length = layoutLength.preferred;
	
	if(length > maxLength) length = maxLength;
	if(length < minLength) length = minLength;
	
	if(this->context.vertical) visibleRect.height = length;
	else                       visibleRect.width = length;
	
	// Position the window
	string placementMethod = getConfigString("Placement", "panel", prefix.c_str());
	Point pos;
	
	if(placementMethod == "panel")
	{
		ScreenbarWindow *window = context->window;
		ScreenbarPanel *panel = dynamic_cast<ScreenbarPanel*>(window);
		if(panel)
		{
			pos = panel->getMenuPos(hoveredElementPos);
			switch(panel->getMenuEdge())
			{
				case ABE_LEFT:   pos.x = panel->getRect().getRight();   break;
				case ABE_BOTTOM: pos.y = panel->getRect().top - visibleRect.height; break;
				case ABE_RIGHT:  pos.x = panel->getRect().left - visibleRect.width; break;
				case ABE_TOP:    pos.y = panel->getRect().getBottom();  break;
			}
		}
	}
	else if(placementMethod == "cursor")
	{
		// TODO
	}
	visibleRect.left = pos.x;
	visibleRect.top = pos.y;
	
	// If the window is partially off-screen, move it on-screen
	Rect monitorRect = monitor->getBoundingRect();
	if(visibleRect.getRight() > monitorRect.getRight())
		visibleRect.left = monitorRect.getRight() - visibleRect.width;
	if(visibleRect.getBottom() > monitorRect.getBottom())
		visibleRect.top = monitorRect.getBottom() - visibleRect.height;
	if(visibleRect.left < monitorRect.left)
		visibleRect.left = monitorRect.left;
	if(visibleRect.top < monitorRect.top)
		visibleRect.top = monitorRect.top;
	
	// Update the window's size/position
	adjustWindowPos();

	// Show the window
	SetWindowPos(window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
	show();
}

ToolTipWindow::~ToolTipWindow()
{
}

LRESULT ToolTipWindow::handleEvent(UINT msg, WPARAM wParam, LPARAM lParam)
{
	return ScreenbarWindow::handleEvent(msg, wParam, lParam);
}
